#include "Gosterici.h"
#include "vtkTextProperty.h"
#include "vtkCaptionActor2D.h"

//====================================================================================================================//
Gosterici::Gosterici(QWidget* parent)
: QVTKWidget(parent)
{
	// Renderer'i olustur ve RenderWindow'la tanistir.
	m_renderer = vtkSmartPointer<vtkRenderer>::New();
	this->GetRenderWindow()->AddRenderer(m_renderer);
	m_renderer->SetBackground(.3, .6, .3);

	// Axes actoru olustur.
	m_axis = vtkSmartPointer<vtkAxesActor>::New();
	m_axis->SetShaftTypeToLine();
	m_axis->SetXAxisLabelText("x");
	m_axis->SetYAxisLabelText("y");
	m_axis->SetZAxisLabelText("z");
	m_axis->SetTotalLength(1.5,1.5,1.5);
	
	// Axes actorunun eksen ozelliklerini olustur.
	vtkSmartPointer<vtkTextProperty> tprop = vtkSmartPointer<vtkTextProperty>::New();
	vtkSmartPointer<vtkTextProperty> tprop2 = vtkSmartPointer<vtkTextProperty>::New();
	vtkSmartPointer<vtkTextProperty> tprop3 = vtkSmartPointer<vtkTextProperty>::New();

	m_axis->GetXAxisCaptionActor2D()->SetCaptionTextProperty(tprop);
	tprop2->ShallowCopy(tprop);
	m_axis->GetYAxisCaptionActor2D()->SetCaptionTextProperty(tprop2);
	tprop3->ShallowCopy(tprop);
	m_axis->GetZAxisCaptionActor2D()->SetCaptionTextProperty(tprop3);

	//m_renderer->AddActor(m_axis);

	// Oryantasyon belirteci koy.
	m_axes_widget = vtkSmartPointer<vtkOrientationMarkerWidget>::New();
	m_axes_widget->SetOutlineColor( 0.9300, 0.5700, 0.1300 );
	m_axes_widget->SetOrientationMarker( m_axis );
	m_axes_widget->SetInteractor( GetRenderWindow()->GetInteractor() );
	m_axes_widget->On();

	// Renderer'i baslat.
	m_renderer->Render();
}

//====================================================================================================================//
Gosterici::~Gosterici() 
{
	// TODO(MEHMET): m_yorunge_map'teki yorungeler icin ayrilan hafizayi temizle!!
}

//====================================================================================================================//
void Gosterici::pozisyonEkle( YorungeId id, const Pozisyon& pozisyon )
{
	// Bu id'ye ait bir yorunge olup olmadigini kontrol et. Yoksa ekle.
	if (!m_yorunge_map.count(id))
		throw new MuyatException("Yorunge henuz eklenmemis!");

	// Id'ye ait yorungeye pozisyonu ekle.
	VtkYorungePtr yorunge = m_yorunge_map.find(id)->second;
	yorunge->pozisyonEkle(pozisyon);
	
	// Yeni eklenen pozisyonlarin da yorunmesi icin goncelle.
	guncelle();
}

//====================================================================================================================//
void Gosterici::yorungeEkle( vtkYorunge* yorunge )
{
	// Yorunge ID'sini map'a ekle ve yeni yorunge olustur.
	m_yorunge_map[yorunge->Id()] = yorunge;
	
	// yeni yorungeyi renderer'a ekle.
	vtkActorCollection *c = yorunge->Actors(); 
	vtkActor *a; 

	c->InitTraversal(); 
	a = c->GetNextItem(); 
	while(a != 0) 
	{ 
		m_renderer->AddActor(a);
		a = c->GetNextItem(); 
	} 
}

//====================================================================================================================//
void Gosterici::yorungeCikar( YorungeId y_id )
{
	// Id'ye denk gelen actorleri cikar.
	
	vtkActorCollection *c = m_yorunge_map[y_id]->Actors(); 
	vtkActor *a; 

	c->InitTraversal(); 
	a = c->GetNextItem(); 
	while(a != 0) 
	{ 
		m_renderer->RemoveActor(a);
		a = c->GetNextItem(); 
	} 
	

	// Id'ye denk gelen yorungeyi map'tan cikar.
	delete m_yorunge_map[y_id];
	m_yorunge_map.erase(y_id);

	
}

//====================================================================================================================//
void Gosterici::guncelle()
{
	// Yorunge map'teki yorungelerin aktorlerini renderer'a ekle.
	std::map<YorungeId,VtkYorungePtr>::const_iterator it;
	for (it = m_yorunge_map.begin(); it != m_yorunge_map.end(); it++)
	{
		VtkYorungePtr yorunge = it->second;
		
		vtkActorCollection *c = yorunge->Actors(); 
		vtkActor *a; 

		c->InitTraversal(); 
		a = c->GetNextItem(); 
		while(a != 0) 
		{ 
			m_renderer->AddActor(a);
			a = c->GetNextItem(); 
		} 
	}
	
	// Yeni eklenen yorungelerin viewport disinda kalmasini engellemek icin reset yapilmali.
	m_renderer->ResetCamera();
	
	// renderer'i baslat.
	this->GetRenderWindow()->Render();
}
